package com.zx.onlineeducation.service.edu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zx.onlineeducation.common.servicebase.exception.OnlineEducationException;
import com.zx.onlineeducation.service.edu.client.VodClient;
import com.zx.onlineeducation.service.edu.entity.*;
import com.zx.onlineeducation.service.edu.entity.vo.CourseInfoVO;
import com.zx.onlineeducation.service.edu.entity.vo.CourseQueryVO;
import com.zx.onlineeducation.service.edu.mapper.CourseMapper;
import com.zx.onlineeducation.service.edu.service.ChapterService;
import com.zx.onlineeducation.service.edu.service.CourseDescriptionService;
import com.zx.onlineeducation.service.edu.service.CourseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zx.onlineeducation.service.edu.service.VideoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author 郑雪
 * @since 2022-01-13
 */
@Service
@Slf4j
public class CourseServiceImpl extends ServiceImpl<CourseMapper, CourseDO> implements CourseService {

    /**
     * 课程Mapper接口
     */
    @Autowired
    private CourseMapper courseMapper;

    /**
     * 课程简介服务接口
     */
    @Autowired
    private CourseDescriptionService courseDescriptionService;

    /**
     * 课程章节服务接口
     */
    @Autowired
    private ChapterService chapterService;

    /**
     * 课程视频服务接口
     */
    @Autowired
    private VideoService videoService;

    /**
     * VOD视频点播服务 远程接口
     */
    @Autowired
    private VodClient vodClient;

    /**
     * 查询课程分页数据列表
     *
     * @param current 当前页
     * @param size 每页显示条数
     * @param courseQueryVO 课程查询对象 {@link CourseQueryVO}
     * @return 分页对象 {@link Page} {@link CourseDO}
     * @author 郑雪
     * @since 2022-01-13
     */
    @Override
    public Page<CourseDO> page(Long current, Long size, CourseQueryVO courseQueryVO) {
        // 1.创建分页对象
        Page<CourseDO> page = new Page<>(current, size);
        // 2.创建条件查询对象
        QueryWrapper<CourseDO> queryWrapper = new QueryWrapper<>();
        String title = courseQueryVO.getTitle();
        String status = courseQueryVO.getStatus();
        if (!StringUtils.isEmpty(title)) {
            queryWrapper.like("title", title);
        }
        if (!StringUtils.isEmpty(status)) {
            queryWrapper.eq("status", status);
        }
        queryWrapper.orderByDesc("create_time");
        // 3.执行分页查询
        this.page(page, queryWrapper);
        return page;
    }

    /**
     * 添加课程基本信息
     *
     * @param courseInfoVO 课程基本信息视图对象 {@link CourseInfoVO}
     * @return 成功true，失败false
     * @author 郑雪
     * @since 2022-01-13
     */
    // @CacheEvict 清空缓存
    @CacheEvict(value = "course", allEntries = true)
    @Override
    public String save(CourseInfoVO courseInfoVO) {
        // 1.添加课程基本信息
        CourseDO courseDO = new CourseDO();
        BeanUtils.copyProperties(courseInfoVO, courseDO);
        boolean saveCourseDO = this.save(courseDO);
        if (!saveCourseDO) {
            throw new OnlineEducationException(20001, "添加课程信息失败！");
        }
        String id = courseDO.getId();

        // 2.添加课程简介
        CourseDescriptionDO courseDescriptionDO = new CourseDescriptionDO();
        BeanUtils.copyProperties(courseInfoVO, courseDescriptionDO);
        courseDescriptionDO.setId(id);
        boolean saveCourseDescription = courseDescriptionService.save(courseDescriptionDO);
        if (!saveCourseDescription) {
            throw new OnlineEducationException(20001, "添加课程信息失败！");
        }
        return id;
    }

    /**
     * 修改课程基本信息
     *
     * @param courseInfoVO 课程基本信息视图对象 {@link CourseInfoVO}
     * @return 成功true，失败false
     * @author 郑雪
     * @since 2022-01-13
     */
    // @CacheEvict 清空缓存
    @CacheEvict(value = "course", allEntries = true)
    @Override
    public boolean updateById(CourseInfoVO courseInfoVO) {
        // 1.修改课程基本信息
        CourseDO courseDO = new CourseDO();
        BeanUtils.copyProperties(courseInfoVO, courseDO);
        boolean updateCourseDO = this.updateById(courseDO);
        if (!updateCourseDO) {
            throw new OnlineEducationException(20001, "修改课程信息失败！");
        }
        String id = courseDO.getId();

        // 2.修改课程简介
        CourseDescriptionDO courseDescriptionDO = new CourseDescriptionDO();
        BeanUtils.copyProperties(courseInfoVO, courseDescriptionDO);
        courseDescriptionDO.setId(id);
        boolean updateCourseDescription = courseDescriptionService.updateById(courseDescriptionDO);
        if (!updateCourseDescription) {
            throw new OnlineEducationException(20001, "修改课程信息失败！");
        }
        return true;
    }

    /**
     * 根据课程ID获取课程基本信息
     *
     * @param courseId 课程ID
     * @return 课程基本信息视图对象 {@link CourseInfoVO}
     * @author 郑雪
     * @since 2022-01-14
     */
    @Override
    public CourseInfoVO getCourseInfoById(String courseId) {
        return courseMapper.selectCourseInfoById(courseId);
    }

    /**
     * 删除课程
     *
     * @param id 课程ID
     * @return 成功true，失败false
     * @author 郑雪
     * @since 2022-01-16
     */
    // @CacheEvict 清空缓存
    @CacheEvict(value = "course", allEntries = true)
    @Override
    public boolean removeCourseById(String id) {

        // 1.删除云端视频资源
        QueryWrapper<VideoDO> videoListQueryWrapper = new QueryWrapper<>();
        videoListQueryWrapper.eq("course_id", id);
        videoListQueryWrapper.select("video_source_id");
        List<VideoDO> videoList = videoService.list(videoListQueryWrapper);
        List<String> videoSourceIdList = videoList.stream()
                    .map(VideoDO::getVideoSourceId)
                    .filter(videoSourceId -> !StringUtils.isEmpty(videoSourceId))
                    .collect(Collectors.toList());
        if (!videoList.isEmpty()) {
            String videoSourceIds = org.apache.commons.lang3.StringUtils.join(videoSourceIdList, ",");
            log.debug("删除课程时要上传的云端视频资源文件Ids：{}", videoSourceIds);
            vodClient.removeVodFile(videoSourceIds);
        }

        // 2.删除视频
        QueryWrapper<VideoDO> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.eq("course_id", id);
        videoService.remove(videoQueryWrapper);

        // 3.删除章节
        QueryWrapper<ChapterDO> chapterQueryWrapper = new QueryWrapper<>();
        chapterQueryWrapper.eq("course_id", id);
        chapterService.remove(chapterQueryWrapper);

        // 4.删除课程简介
        boolean removeDescription = courseDescriptionService.removeById(id);

        // 5.删除课程
        boolean removeCourse = this.removeById(id);

        // 6.返回结果
        if (!removeCourse || !removeDescription) {
            throw new OnlineEducationException(20001, "删除失败");
        }
        return true;
    }

    /**
     * 获取热门课程数据列表
     *
     * @param courseLimit 热门课程显示条数
     * @return CourseDO对象的List集合 {@link CourseDO}
     * @author 郑雪
     * @since 2022-01-25
     */
    // @Cacheable 将返回结果进行缓存，以后查询数据，直接从缓存中取，key生成规则：value::key ，例如：course::selectIndexList
    @Cacheable(value = "course", key = "'selectIndexList'")
    @Override
    public List<CourseDO> getHotCourseList(Integer courseLimit) {
        QueryWrapper<CourseDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        queryWrapper.last("limit " + courseLimit);
        return this.list(queryWrapper);
    }

}
